package my.springboot3.service.impl;

import lombok.extern.slf4j.Slf4j;
import my.springboot3.dto.Respond;
import my.springboot3.dto.entity.User;
import my.springboot3.exception.errorException;
import my.springboot3.mapper.UserMapper;
import my.springboot3.service.UserService;
import my.springboot3.utils.JwtUtil;
import my.springboot3.utils.Md5Util;
import my.springboot3.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.LocalDateTime;
import java.util.HashMap;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    // redis服务
    @Autowired
    private RedisServiceImpl redisService;

    @Override
    public User findById(int id) {
        return userMapper.findById(id);
    }



    @Override
    public Respond<Void> register(User user){
        try {
            //账号密码查询,非空判断,如果账号密码异常则抛出异常处理
            if (userMapper.findByUsername(user.getUsername()) != null) {
                throw new Exception("用户名已存在,注册失败！");
            }
            // 对密码进行加密
            user.setPassword(Md5Util.getMD5String(user.getPassword()));
            if (userMapper.add(user)<=0) {
                // 注册失败
                throw new Exception("数据异常,注册失败！");
            }
            return Respond.success();
        }catch (Exception e){
            return Respond.error(e.getMessage());
        }

    }

    /**
     * 用户登录,1-检查用户名是否存在,2-检查密码是否正确,3-给出jwt令牌
     *
     * @param user 用户对象
     * @return
     * @throws Exception
     */
    // @Override
    // public Respond<?> login(User user) {
    //     if (user == null) {
    //         throw new errorException("该用户不存在,请检查账号或者注册新账号");
    //     }
    //     User checkUser = userMapper.findByUsername(user.getUsername());
    //     //  对用户名和密码进行校验
    //     if (!Md5Util.checkPassword(user.getPassword(), checkUser.getPassword())) {
    //         //登录失败
    //         throw new errorException("用户名或密码错误！");
    //     }
    //     // 给出jwt令牌
    //     HashMap<String, Object> claims = new HashMap<>();
    //     // 将用户id和用户名放入jwt令牌中
    //     claims.put("id", checkUser.getId());
    //     claims.put("username", checkUser.getUsername());
    //     String token = JwtUtil.genToken(claims);
    //     // 将jwt令牌存入redis中
    //
    //     return Respond.success(token);
    //
    // }

    @Override
    public Respond<?> login(@RequestParam String username, @RequestParam String password) {
        User checkUser = userMapper.findByUsername(username);

        if (checkUser == null) {
            throw new errorException("该用户不存在,请检查账号或者注册新账号");
        }
        //  对用户名和密码进行校验
        if (!Md5Util.checkPassword(password, checkUser.getPassword())) {
            //登录失败
            throw new errorException("用户名或密码错误！");
        }
        // 给出jwt令牌
        HashMap<String, Object> claims = new HashMap<>();
        // 将用户id放入jwt令牌中
        claims.put("id", checkUser.getId());
        // claims.put("username", checkUser.getUsername());
        String token = JwtUtil.genToken(claims);
        // 将jwt令牌存入redis中
        redisService.set(String.valueOf(checkUser.getId()), token);

        return Respond.success(token);

    }

    /**
     * 获取用户信息
     *
     * @param token
     * @return
     */
    @Override
    public Respond<?> userInfo() {
        // 获取用户id, 从ThreadLocal中获取
        Integer id = (Integer)ThreadLocalUtil.get();
        // 根据id查询用户信息
        User user = userMapper.findById(id);
        return Respond.success(user);
    }

    /**
     * 修改用户信息,只修改昵称\邮件\更新时间
     *
     * @param user
     * @return
     */
    @Override
    public Respond<Void> update(User user) {
        // 获取用户id
        Integer id = (Integer)ThreadLocalUtil.get();
        user.setId(id);
        // 修改相应id的用户信息
        user.setUpdateTime(LocalDateTime.now());
        // 更新用户信息,mapper中只对昵称\邮件\更新时间进行更新
        userMapper.updateAll(user);
        return Respond.success();

    }

    /**
     * 更新用户密码
     *
     * @param oldPwd 旧密码
     * @param newPwd 新密码
     * @param rePwd  重复密码
     */
    @Override
    public void updatePwd(String oldPwd, String newPwd, String rePwd) {
        if (!newPwd.equals(rePwd)) {
            // 检查两个新密码是否一致
            throw new errorException("两次密码不一致");
        }
        // 检查旧密码是否正确
        Integer id = (Integer)ThreadLocalUtil.get();  // 获取用户id
        String password = userMapper.findById(id).getPassword();// 获取用户密码
        if (Md5Util.checkPassword(oldPwd, password)) {
            // 修改密码
            userMapper.updatePwd(Md5Util.getMD5String(newPwd), id);
        } else {
            throw new errorException("旧密码错误");
        }
        // 清除token,重新登录,将token拉出redis白名单
        ThreadLocalUtil.clear();
        redisService.delete(String.valueOf(id));

    }

    /**
     * 更新用户头像
     */
    @Override
    public void updatePic(String avatarUrl) {
        Integer id = (Integer)ThreadLocalUtil.get();
        userMapper.updateAvatar(avatarUrl,id);
    }


}
